﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace BaseHelper.Net
{
    public class UdpHelper
    {

        public delegate void DataArriveHandler(string remoteIP, byte[] buffer);
        public event DataArriveHandler DataArriveEvent;

        private IPEndPoint iepAsc;

        private UdpClient udpClient;
        private Thread thGetData;

        public void Start(int Port)
        {
            Close();

            IPEndPoint localIpep = new IPEndPoint(IPAddress.Any, Port); // 本机IP和监听端口号
            udpClient = new UdpClient(localIpep);
           
            thGetData = new Thread(ReceiveMessage);
            thGetData.Start();
        }

        public void Close()
        {
            try
            {
                if (thGetData != null)
                {
                    thGetData.Abort();
                    thGetData = null;
                }
            }
            catch { }

            try
            {

                if (udpClient != null)
                {
                    udpClient.Close();
                    udpClient = null;
                }
            }
            catch { }
        }

        private void ReceiveMessage(object obj)
        {
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);//
            while (true)
            {
                try
                {

                    byte[] data = udpClient.Receive(ref remoteIpep);
                    if (DataArriveEvent != null)
                        DataArriveEvent(remoteIpep.Address.ToString(), data);
                }
                catch
                {

                }
            }
        }


        public static void Send(string IP, int Port, byte[] Data)
        {
            using (UdpClient udp = new UdpClient())
            {
                IPEndPoint iep = new IPEndPoint(IPAddress.Parse(IP), Port);
                udp.Send(Data, Data.Length, iep);
            }
        }

        public void BeginReceive(int Port)
        {
            Close();

  
            iepAsc = new IPEndPoint(IPAddress.Any, Port);

            udpClient = new UdpClient(iepAsc);
            udpClient.BeginReceive(new AsyncCallback(this.ReceiveCallback), null);

        }

        private void ReceiveCallback(IAsyncResult result)
        {
            IPEndPoint iepRemote = new IPEndPoint(IPAddress.Any, 0);
            try
            {
                byte[] buffer = this.udpClient.EndReceive(result, ref iepRemote);

                if (DataArriveEvent != null)
                    DataArriveEvent(iepRemote.Address.ToString(), buffer);
            }
            catch
            {
                
            }
            finally
            {
                udpClient.BeginReceive(new AsyncCallback(this.ReceiveCallback), null);
            }
   

        }

        public void BeginSend(string IP, int Port, byte[] buffer)
        {
            IPEndPoint remoteIP = new IPEndPoint(IPAddress.Parse(IP), Port);
            udpClient.BeginSend(buffer, buffer.Length, remoteIP, new AsyncCallback(SendCallback), null);

        }

        private void SendCallback(IAsyncResult result)
        {
            try
            {
                udpClient.EndSend(result);
            }
            catch
            {
                
            }
        }


    }
}
